<template>
    <div class="img-verify">
        <canvas width="120" height="40" ref="verify" @click="changeVerify"></canvas>
    </div>
</template>

<script setup lang='ts'>
import { reactive, onMounted, ref } from 'vue';
const verify: any = ref(null);
const state = reactive({
    pool: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',
    imgCode: 'draw'
})
onMounted(() => {
    //开始生成验证码
    state.imgCode = draw()
})

//生成随机数
const randomNum = (min: number, max: number): number => {
    return parseInt(`${Math.random() * (max - min) + min}`)
}
//随机生成颜色
const randomColor = (min: number, max: number): string => {
    const r = randomNum(min, max)
    const g = randomNum(min, max)
    const b = randomNum(min, max)
    return `rgb(${r},${g},${b})`
}
const draw = (): string => {
    const ctx = verify.value.getContext('2d')
    ctx.fillStyle = randomColor(180, 230)
    ctx.fillRect(0, 0, 120, 40)
    let imgCode = ''
    for (let i = 0; i < 4; i++) {
        const text = state.pool[randomNum(0, state.pool.length)]
        imgCode += text
        const fontSize = randomNum(18, 40)
        const deg = randomNum(-30, 30)
        ctx.font = fontSize + 'px simhei'
        ctx.textBaseline = 'top'
        ctx.fillStyle = randomColor(80, 150)
        ctx.save()
        ctx.translate(30 * i + 15, 15)
        ctx.rotate((deg * Math.PI) / 180)
        ctx.fillText(text, -10, -15)
        ctx.restore()
    }
    //随机生成五条干扰线，干扰线的颜色要浅一点
    for (let i = 0; i < 5; i++) {
        ctx.beginPath()
        ctx.moveTo(randomNum(0, 120), randomNum(0, 40))
        ctx.lineTo(randomNum(0, 120), randomNum(0, 40))
        ctx.strokeStyle = randomColor(180, 230)
        ctx.closePath()
        ctx.stroke()
    }
    //随机产生48个干扰小点
    for (let i = 0; i < 48; i++) {
        ctx.beginPath()
        ctx.arc(
            randomNum(0, 120), randomNum(0, 40), 1, 0, 2 * Math.PI
        )
        ctx.closePath()
        ctx.fillStyle = randomColor(150, 200);
        ctx.fill()

    }
    sentimgCode(imgCode)
    return imgCode
}
const emits = defineEmits(['sentimgCode'])
const changeVerify = (): void => {
    state.imgCode = draw()
}
const sentimgCode = (imgCode: string) => {
    emits("sentimgCode", imgCode)
}
defineExpose({
    changeVerify
})
</script>

<style lang='less' scoped></style>
